package com.ruoyi.flow.flow.identity.activiti;

import com.ruoyi.flow.core.exception.BadRequestException;
import com.ruoyi.flow.flow.identity.activiti.entity.FlowDept;
import com.ruoyi.flow.flow.identity.activiti.entity.FlowUser;
import com.ruoyi.flow.flow.identity.activiti.entity.FlowUserDeptRelation;
import com.ruoyi.flow.flow.identity.activiti.enums.Status;
import com.ruoyi.flow.flow.identity.activiti.repository.FlowDeptRepository;
import com.ruoyi.flow.flow.identity.activiti.repository.FlowUserDeptRelationRepository;
import com.ruoyi.flow.flow.identity.activiti.repository.FlowUserRepository;
import com.google.common.collect.Lists;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.UserQueryImpl;
import org.activiti.engine.impl.persistence.entity.UserEntity;
import org.activiti.engine.impl.persistence.entity.data.UserDataManager;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author wtian
 * @version 1.0
 * @since 2018/9/6 9:31
 */
public class FlowUserDataManager implements UserDataManager {
    private static final Logger LOGGER = LoggerFactory.getLogger(FlowUserDataManager.class);
    @Autowired
    private FlowUserRepository flowUserRepository;
    @Autowired
    private FlowUserDeptRelationRepository flowUserDeptRelationRepository;
    @Autowired
    private FlowDeptRepository flowDeptRepository;

    @Override
    public UserEntity create() {
        throw new BadRequestException("Flow user manager does not support creating new user.");
    }

    @Override
    public UserEntity findById(String entityId) {
        return flowUserRepository.findById(entityId);
    }

    @Override
    public void insert(UserEntity entity) {
        throw new BadRequestException("Flow user manager does not support creating new user.");
    }

    @Override
    public UserEntity update(UserEntity entity) {
        throw new BadRequestException("Flow user manager does not support creating new user.");
    }

    @Override
    public void delete(String id) {
        throw new BadRequestException("Flow user manager does not support delete user.");
    }

    @Override
    public void delete(UserEntity entity) {
        throw new BadRequestException("Flow user manager does not support delete user.");
    }

    @Override
    public List<User> findUserByQueryCriteria(UserQueryImpl query, Page page) {
        if (StringUtils.isNotEmpty(query.getId())) {
            List<User> users = Lists.newArrayList();
            users.add(findById(query.getId()));
            return users;
        } else if (StringUtils.isNotEmpty(query.getFullNameLike())) {
            List<FlowUser> flowUsers = flowUserRepository.findByFirstNameLikeAndStatusIsNot(query.getFullNameLike(), Status.INACTIVE);
            List<User> users = Lists.newArrayList();
            users.addAll(flowUsers);
            return users;
        } else if (StringUtils.isNotEmpty(query.getFirstName())) {
            FlowUser flowUser = flowUserRepository.findByFirstName(query.getFirstName());
            List<User> users = Lists.newArrayList();
            users.add(flowUser);
            return users;
        } else if (StringUtils.isNotEmpty(query.getEmail())) {
            return Lists.newArrayList();
        } else if (StringUtils.isNotEmpty(query.getProcDefId())) {
            return Lists.newArrayList();
        } else if (StringUtils.isNotEmpty(query.getGroupId())) {
            FlowDept dept = flowDeptRepository.findById(query.getGroupId());
            List<User> users = Lists.newArrayList();
            if (Objects.nonNull(dept)) {
                int deptId = dept.getDeptid();
                List<FlowUserDeptRelation> relations = flowUserDeptRelationRepository.findByDeptid(deptId);
                for (FlowUserDeptRelation relation : relations) {
                    users.add(relation.getUser());
                }
            }
            return users;
        } else if (StringUtils.isNotEmpty(query.getEmailLike())) {
            return Lists.newArrayList();
        } else {
            List<FlowUser> flowUsers = flowUserRepository.findAllByStatusIsNot(Status.INACTIVE);
            List<User> users = Lists.newArrayList();
            users.addAll(flowUsers);
            return users;
        }
    }

    @Override
    public long findUserCountByQueryCriteria(UserQueryImpl query) {
        return findUserByQueryCriteria(query, null).size();
    }

    @Override
    public List<Group> findGroupsByUser(String userId) {
        FlowUser flowUser = (FlowUser) findById(userId);
        if (Objects.nonNull(flowUser)) {
            List<FlowUserDeptRelation> relations = flowUserDeptRelationRepository.findByUserid(flowUser.getUserid());
            List<Group> groups = Lists.newArrayList();
            if (relations != null && relations.size() > 0) {
                for (FlowUserDeptRelation relation : relations) {
                    FlowDept dept = flowDeptRepository.findById(relation.getDeptid()).get();
                    groups.add(dept);
                }
            }
            return groups;
        }
        return Lists.newArrayList();
    }

    @Override
    public List<User> findUsersByNativeQuery(Map<String, Object> parameterMap, int firstResult, int maxResults) {
        throw new BadRequestException("Flow user manager does not support this option.");
    }

    @Override
    public long findUserCountByNativeQuery(Map<String, Object> parameterMap) {
        throw new BadRequestException("Flow user manager does not support this option.");
    }
}
